﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace SurveyHost.Support
{
    public static class StringExtensions
    {
        /* The reason for this trickery is so that you can mock the context in tests.
         * Use an accessor to mock _context prior to running tests.
         * */
#pragma warning disable 0649
        private static HttpContextBase _context;
#pragma warning restore 0649
        private static HttpContextBase Context { get { return _context ?? new HttpContextWrapper(HttpContext.Current); } }
        /// <summary>
        /// Replaces the current string with the value of <paramref name="ifNullOrEmpty"/> if the current string is null or empty.
        /// </summary>
        /// <remarks>This method also <seealso cref="HtmlEncode"/>s the result.  Be careful about chaining this method with other extensions
        /// that encode their output.</remarks>
        /// <param name="me">The string to test</param>
        /// <param name="ifNullOrEmpty">The string to replace the current string with if it is null or empty</param>
        /// <returns><paramref name="ifNullOrEmpty"/> if <paramref cref="me"/> is empty, <paramref cref="me"/> otherwise.</returns>
        public static string Or(this string me, string ifNullOrEmpty)
        {
            return string.IsNullOrEmpty(me) ? ifNullOrEmpty.HtmlEncode() : me.HtmlEncode();
        }
        /// <summary>
        /// Html encodes the string.
        /// </summary>
        /// <remarks>If <paramref name="me"/> is null or empty, <seealso cref="string.Empty"/> is returned.</remarks>
        /// <param name="me">The string to encode</param>
        /// <returns>The string, html encoded; <seealso cref="string.Empty"/> if <paramref name="me"/> is null or empty.</returns>
        public static string HtmlEncode(this string me)
        {
            if (string.IsNullOrEmpty(me)) return string.Empty;
            return Encode(me);
        }
        /// <summary>
        /// Html encodes the string, or returns the html encoded value of <paramref name="isNull"/>
        /// </summary>
        /// <param name="me">The string to encode</param>
        /// <param name="ifNull">The string to html encode if <paramref name="me"/> is null.</param>
        /// <returns>The string, html encoded</returns>
        public static string HtmlEncode(this string me, string ifNull)
        {
            if (string.IsNullOrEmpty(me)) return Encode(ifNull);
            return Encode(me);
        }

        /// <summary>
        /// Html encodes the given string if not null or empty, returning <seealso cref="string.Empty"/> otherwise.
        /// </summary>
        /// <param name="toEncode">To encode.</param>
        /// <returns></returns>
        private static string Encode(string toEncode)
        {
            if (string.IsNullOrEmpty(toEncode)) return string.Empty;
            return Context.Server.HtmlEncode(toEncode);
        }

        /// <summary>
        /// Determines if <paramref name="me"/> is <c>null</c> or empty.
        /// </summary>
        /// <param name="me">The string to check.</param>
        /// <returns>
        /// 	<c>true</c> if <paramref name="me"/> is <c>null</c> or empty; otherwise, <c>false</c>.
        /// </returns>
        public static bool IsNullOrEmpty(this string me)
        {
            return string.IsNullOrEmpty(me);
        }

        /// <summary>
        /// Formats the given <paramref name="me">string</paramref> with the given <paramref name="args">arguments</paramref>
        /// </summary>
        /// <param name="me">The <paramref name="me">string</paramref> to format.</param>
        /// <param name="args">The format <paramref name="args">arguments</paramref> to use.</param>
        /// <returns>A formatted <seealso cref="string"/></returns>
        public static string FormatMe(this string me, params object[] args)
        {
            return string.Format(me, args);
        }
    }
}
